package com.getpebble.android.framework.install.firmware;

import android.content.Context;
import android.net.Uri;
import com.getpebble.android.PebbleApplication;
import com.getpebble.android.common.core.async.PblAsyncTask;
import com.getpebble.android.common.core.trace.Trace;
import com.getpebble.android.common.model.FrameworkState;
import com.getpebble.android.common.model.PblDevice;
import com.getpebble.android.framework.comm.MessageRouter;
import com.getpebble.android.framework.endpoint.InstallFirmwareEndpointSet;
import com.getpebble.android.framework.endpoint.InstallFirmwareEndpointSet.FirmwareInstallResult;
import com.getpebble.android.framework.firmware.FirmwareManifestSync;

public class FirmwareInstallManager {
    public static final String TAG = FirmwareInstallManager.class.getSimpleName();
    private Listener mListener;
    private boolean mWasInPrfEndpointSet;

    private class Listener implements com.getpebble.android.framework.endpoint.InstallFirmwareEndpointSet.Listener {
        private FrameworkState mFrameworkState;
        private MessageRouter mMessageRouter;

        public Listener(MessageRouter messageRouter, FrameworkState frameworkState) {
            this.mMessageRouter = messageRouter;
            this.mFrameworkState = frameworkState;
        }

        public void installFail(FirmwareInstallResult result) {
            Trace.debug(FirmwareInstallManager.TAG, "Install failed with result: " + result.toString());
            FirmwareInstallManager.this.sendInstallResultEvent(this.mMessageRouter, this.mFrameworkState, result);
        }

        public void installSuccess(FirmwareInstallResult result) {
            FirmwareInstallManager.this.sendInstallResultEvent(this.mMessageRouter, this.mFrameworkState, result);
        }

        public void installProgressUpdate(int percentage) {
            this.mFrameworkState.setFirmwareInstallProgress(percentage);
        }
    }

    public FirmwareInstallManager(Context context) throws IllegalArgumentException {
        if (context == null) {
            throw new IllegalArgumentException("'context' cannot be null!");
        }
    }

    private Context getContext() {
        return PebbleApplication.getAppContext();
    }

    public void installFirmware(final MessageRouter messageRouter, final Uri firmwareUri, final FrameworkState frameworkState) throws IllegalArgumentException {
        Trace.debug(TAG, "installFirmware() device = " + messageRouter.getDevice() + " uri = " + firmwareUri);
        checkInstallArguments(messageRouter, frameworkState);
        this.mWasInPrfEndpointSet = messageRouter.isInPrfEndpointSet();
        if (firmwareUri == null) {
            throw new IllegalArgumentException("'firmwareUri' cannot be null!");
        }
        new PblAsyncTask() {
            public boolean doInBackground() {
                FirmwareInstallManager.this.installBundle(FirmwareInstallManager.this.fetchFirmwareBundle(firmwareUri), messageRouter, frameworkState);
                return true;
            }

            public void onTaskSuccess() {
            }

            public void onTaskFailed() {
            }
        }.submit();
    }

    public void installFirmwareForRecovery(final MessageRouter messageRouter, final FrameworkState frameworkState) throws IllegalArgumentException {
        Trace.debug(TAG, "installFirmwareForRecovery() device = " + messageRouter.getDevice());
        checkInstallArguments(messageRouter, frameworkState);
        this.mWasInPrfEndpointSet = messageRouter.isInPrfEndpointSet();
        new PblAsyncTask() {
            public boolean doInBackground() {
                FirmwareInstallManager.this.installBundle(FirmwareInstallManager.this.fetchLatestFirmwareBundle(messageRouter.getDevice()), messageRouter, frameworkState);
                return true;
            }

            public void onTaskSuccess() {
            }

            public void onTaskFailed() {
            }
        }.submit();
    }

    private void checkInstallArguments(MessageRouter messageRouter, FrameworkState frameworkState) throws IllegalArgumentException {
        if (messageRouter == null) {
            throw new IllegalArgumentException("'messageRouter' cannot be null");
        } else if (frameworkState == null) {
            throw new IllegalArgumentException("'frameworkState' cannot be null!");
        } else if (this.mListener != null) {
            throw new IllegalStateException("Cannot start firmware install, already ongoing!");
        } else if (getContext() == null) {
            throw new IllegalStateException("context is null");
        }
    }

    private void installBundle(FirmwareBundle firmwareBundle, MessageRouter messageRouter, FrameworkState frameworkState) {
        if (firmwareBundle == null) {
            Trace.error(TAG, "Failed to find bundle");
            sendInstallResultEvent(messageRouter, frameworkState, FirmwareInstallResult.BUNDLE_NOT_FOUND);
            return;
        }
        this.mListener = new Listener(messageRouter, frameworkState);
        InstallFirmwareEndpointSet endpointSet = new InstallFirmwareEndpointSet(messageRouter, firmwareBundle, this.mListener, getContext().getContentResolver());
        if (messageRouter.setCurrentEndpointSet(endpointSet)) {
            endpointSet.startInstall();
            return;
        }
        Trace.debug(TAG, "Couldn't set firmware install endpoint set");
        sendInstallResultEvent(messageRouter, frameworkState, FirmwareInstallResult.ENDPOINT_NOT_ACTIVE);
        firmwareBundle.closeFile();
    }

    private FirmwareBundle fetchFirmwareBundle(Uri firmwareUri) {
        if (getContext() != null) {
            return (FirmwareBundle) new FirmwareBundleManager(getContext()).fetchBundleFromUri(firmwareUri);
        }
        Trace.error(TAG, "Cannot get firmware bundle, context is null");
        return null;
    }

    private FirmwareBundle fetchLatestFirmwareBundle(PblDevice device) {
        String latestFirmwareUriStr = new FirmwareManifestSync(getContext()).fetchLatestFirmwareUriForDevice(device);
        if (latestFirmwareUriStr != null) {
            return (FirmwareBundle) new FirmwareBundleManager(getContext()).fetchBundleFromUri(Uri.parse(latestFirmwareUriStr));
        }
        Trace.debug(TAG, "No firmware found for device.");
        return null;
    }

    private void sendInstallResultEvent(MessageRouter messageRouter, FrameworkState frameworkState, FirmwareInstallResult firmwareInstallResult) {
        Trace.debug(TAG, "Sending install result: " + firmwareInstallResult);
        frameworkState.setFirmwareInstallResult(firmwareInstallResult.getCode());
        cleanup(messageRouter);
    }

    private void cleanup(MessageRouter messageRouter) {
        if (this.mWasInPrfEndpointSet) {
            messageRouter.setEndpointSetToPrf(getContext());
        } else {
            messageRouter.setEndpointSetToDefault(getContext());
        }
        this.mListener = null;
    }
}
